import { getUserServerSession } from '@/server/auth';
import { initTRPC, TRPCError } from '@trpc/server';
import { headers } from 'next/headers';
import { db } from '../db/db';

const t = initTRPC.context().create();
const { router, procedure } = t;

const withLoggerProcedure = procedure.use(async ({ ctx, next }) => {
  const start = Date.now();

  const result = await next();

  console.info('Calling Api Time', Date.now() - start);

  return result;
});

export const withSessionMiddleware = t.middleware(async ({ ctx, next }) => {
  const session = await getUserServerSession();

  return next({
    ctx: {
      session,
    },
  });
});

export const protectedProcedure = withLoggerProcedure
  .use(withSessionMiddleware)
  .use(async ({ ctx, next }) => {
    if (!ctx.session?.user) {
      throw new TRPCError({
        code: 'UNAUTHORIZED',
      });
    }

    return next({
      ctx: {
        ...ctx,
        session: ctx.session!,
      },
    });
  });

export const withAppProcedure = withLoggerProcedure.use(async ({ next }) => {
  const header = await headers();

  const apiKeyHeader = header.get('x-api-key');

  if (!apiKeyHeader)
    throw new TRPCError({
      code: 'FORBIDDEN',
    });

  const apiKey = await db.query.apiKeys.findFirst({
    where: (apiKeys, { eq, and, isNotNull }) =>
      and(eq(apiKeys.key, apiKeyHeader), isNotNull(apiKeys.appId)),
    with: {
      app: {
        with: {
          user: true,
        },
      },
    },
  });

  if (!apiKey?.app.user) {
    throw new TRPCError({
      code: 'UNAUTHORIZED',
    });
  }

  return next({
    ctx: {
      app: apiKey.app,
      user: apiKey.app.user,
    },
  });
});

export { router };
